package org.framework.common.api.service.bo;

import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.framework.common.api.entity.CommonEntityAware;
import org.framework.common.api.query.Criterion.Operator;
import org.framework.common.api.support.model.ChosenModel;
import org.framework.common.api.support.model.FormModel;
import org.framework.common.api.support.model.PageModel;
import org.framework.common.api.support.model.QueryModel;
import org.framework.common.api.support.model.TreeModel;
import org.springframework.ui.ModelMap;


/**
 * <p>描述: 公共业务接口的适配器类，不同的业务实现类可根据需要覆盖该类中的接口。</p>
 * <p>Company:上海中信信息发展股份有限公司</p>
 * @author chanlong(陈龙)
 * @date 2013年12月10日  下午4:37:27
 * @version 1.0.2013.
 */
public abstract class CommonBoAdapter<ENTITY extends CommonEntityAware<ID>, ID extends Serializable> implements CommonBoAware<ENTITY, ID> {

	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#update(java.lang.Object)
	 * @author chanlong(陈龙)
	 * @date 2013年12月23日 上午11:06:31
	 */
	@Override
	public ENTITY update(final ENTITY entity) throws Exception {
		return null;
	}

	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#update(org.framework.common.api.entity.CommonEntityAware, java.lang.String, java.lang.Object)
	 * @author chanlong(陈龙)
	 * @date 2016年4月9日 下午6:28:54
	 */
	@Override
	public void update(final ENTITY entity, final String field, final Object value) throws Exception {
	}

	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#updateAll(java.util.List)
	 * @author chanlong(陈龙)
	 * @date 2013年12月23日 上午11:06:31
	 */
	@Override
	public void updateAll(final List<ENTITY> entities) throws Exception {
	}

	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#delete(ces.framework.common.entity.CommonEntity)
	 * @author chanlong(陈龙)
	 * @date 2014年3月3日 上午10:42:17
	 */
	@Override
	public void delete(final ENTITY entity) throws Exception {
		
	}
	
	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#delete(java.lang.Object)
	 * @author chanlong(陈龙)
	 * @date 2013年12月23日 上午11:06:31
	 */
	@Override
	public void delete(final Class<ENTITY> cls, final ID id) throws Exception {
	}

	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#deleteAll(java.lang.Object[])
	 * @author chanlong(陈龙)
	 * @date 2013年12月23日 上午11:06:31
	 */
	@Override
	@SuppressWarnings("unchecked")
	public void deleteAll(final Class<ENTITY> cls, final ID... ids) throws Exception {
	}

	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#insert(java.lang.Object)
	 * @author chanlong(陈龙)
	 * @date 2013年12月23日 上午11:06:31
	 */
	@Override
	public ENTITY insert(final ENTITY entity) throws Exception {
		return null;
	}

	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#insertAll(java.util.List)
	 * @author chanlong(陈龙)
	 * @date 2013年12月23日 上午11:06:31
	 */
	@Override
	public List<ENTITY> insertAll(final List<ENTITY> entities) throws Exception {
		return null;
	}

	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#insertRelation(org.framework.common.api.entity.CommonEntityAware)
	 * @author chanlong(陈龙)
	 * @date 2016年2月3日 下午12:36:56
	 */
	@Override
	public ENTITY insertRelation(final ENTITY entity) throws Exception {
		return null;
	}
	
	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#insertRelations(java.util.List)
	 * @author chanlong(陈龙)
	 * @date 2016年2月3日 下午12:16:20
	 */
	@Override
	public ENTITY insertRelations(final ENTITY entity) throws Exception {
		return null;
	}
	
	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#loader(ces.framework.common.entity.CommonEntity)
	 * @author Administrator(陈龙)
	 * @date 2014-1-22 下午2:07:35
	 */
	@Override
	public ENTITY loader(final ENTITY entity) throws Exception {
		return null;
	}
	
	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#loader(java.lang.Class, java.io.Serializable)
	 * @author chanlong(陈龙)
	 * @date 2013年12月28日 下午1:55:48
	 */
	@Override
	public ENTITY loader(final Class<ENTITY> cls, final ID id) throws Exception {
		return null;
	}
	
	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#loader(java.lang.Class, java.util.Map)
	 * @author chanlong(陈龙)
	 * @date 2016年8月30日 上午11:56:50
	 */
	@Override
	public ENTITY loader(final Class<ENTITY> cls, final Map<String,Object> params) throws Exception {
		return null;
	}
	
	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#loader(java.lang.Class, java.lang.String, java.lang.Object)
	 * @author chanlong(陈龙)
	 * @date 2014年4月25日 下午9:21:17
	 */
	@Override
	public ENTITY loader(final Class<ENTITY> cls, final String field, final Object value) throws Exception {
		return null;
	}
	
	/**
	 * @see ces.framework.common.web.dbo.CommonBoAware#findByIds(java.lang.Class, java.lang.String[])
	 * @author chanlong(陈龙)
	 * @date 2014年3月3日 上午10:42:17
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<ENTITY> findByIds(final Class<ENTITY> cls, final ID... ids) throws Exception {
		return null;
	}
	
	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#count(org.framework.common.api.support.model.QueryModel)
	 * @author chanlong(陈龙)
	 * @date 2016年4月13日 下午3:17:41
	 */
	@Override
	public long count(final QueryModel model) throws Exception {
		return 0;
	}
	
	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#findByQuery(java.lang.Class, org.framework.common.api.support.model.QueryModel)
	 * @author chanlong(陈龙)
	 * @date 2016年1月19日 下午6:13:56
	 */
	@Override
	public PageModel<ENTITY> findByQuery(final QueryModel query) throws Exception {
		return null;
	}
	
	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#select(org.framework.common.api.support.model.FormModel)
	 * @author chanlong(陈龙)
	 * @date 2016年1月30日 上午10:15:48
	 */
	@Override
	public ChosenModel[] select(final FormModel model) throws Exception{
		return null;
	}

	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#tree(org.framework.common.api.support.model.FormModel)
	 * @author chanlong(陈龙)
	 * @date 2016年3月30日 上午10:57:30
	 */
	@Override
	public TreeModel[] tree(final QueryModel model) throws Exception {
		return null;
	}
	
	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#maxcode()
	 * @author chanlong(陈龙)
	 * @date 2016年1月23日 下午7:15:59
	 */
	@Override
	public String maxcode() throws Exception {
		return null;
	}
	
	/* ===========================================
	 * 构造查询参数，用于构造条件map
	 * =========================================== */
	protected Map<String,Object> params;
	
	/**
	 * 清除查询参数.
	 * @author chanlong(陈龙)
	 * @date 2016年4月10日 下午1:40:24
	 */
	protected void clearParams() {
		if(params != null && !params.isEmpty()){
			params.clear();
			params = null;
		}
	}

	/**
	 * @see org.framework.common.api.service.bo.CommonBoAware#addParameter(java.lang.String, java.lang.Object)
	 * @author chanlong(陈龙)
	 * @date 2016年4月9日 下午7:21:37
	 */
	@Override
	public CommonBoAdapter<ENTITY, ID> addParameter(final String key, final Object value){
		if(params == null){
			params = new HashMap<String,Object>();
		}
		params.put(key, value);
		return this;
	}
	
	/* ===========================================
	 * 构造查询参数，用于拼接jpql语句
	 * =========================================== */
	private StringBuilder jpql;
	
	/**
	 * 要查询的实体.
	 * @param entityName
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年4月9日 下午7:24:48
	 */
	protected CommonBoAdapter<ENTITY, ID> from(final String entityName){
		jpql = new StringBuilder("select o from ").append(entityName).append(" o where 1=1 ");
		return this;
	}
	
	/**
	 * 构造jpql的where条件.
	 * @param map
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年4月9日 下午7:24:13
	 */
	protected String where(final ModelMap map){
		if(map != null && !map.isEmpty()){
			Set<String> keys = map.keySet();
			for (String key : keys) {
				String[] fields = StringUtils.split(key, "_");
				String field = fields[0];
				String operator = fields.length > 1 ? fields[1] : Operator.EQ.name();
				
				switch (Operator.valueOf(operator)) {
					case EQ:
						jpql.append(" and o.").append(field).append(" = :").append(field);
					break;
					case GT:
						jpql.append(" and o.").append(field).append(" > :").append(field);
					break;
					case LT:
						jpql.append(" and o.").append(field).append(" < :").append(field);
					break;
					case GE:
						jpql.append(" and o.").append(field).append(" >= :").append(field);
					break;
					case LE:
						jpql.append(" and o.").append(field).append(" <= :").append(field);
					break;
					case LIKE:
						jpql.append(" and o.").append(field).append(" like :").append(field);
					break;
					default:
						jpql.append(" and o.").append(field).append(" = :").append(field);
					break;
				}
			}
		}
		return jpql.toString();
	}
}
